package worldwind;

import gov.nasa.worldwind.BasicModel;
import gov.nasa.worldwind.Model;
import gov.nasa.worldwind.View;
import gov.nasa.worldwind.awt.WorldWindowGLJPanel;
import gov.nasa.worldwind.event.PositionEvent;
import gov.nasa.worldwind.event.PositionListener;
import gov.nasa.worldwind.event.RenderingEvent;
import gov.nasa.worldwind.event.RenderingListener;
import gov.nasa.worldwind.event.SelectEvent;
import gov.nasa.worldwind.event.SelectListener;
import gov.nasa.worldwind.geom.Angle;
import gov.nasa.worldwind.geom.LatLon;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.geom.Sector;
import gov.nasa.worldwind.globes.Globe;
import gov.nasa.worldwind.layers.CompassLayer;
import gov.nasa.worldwind.layers.IconLayer;
import gov.nasa.worldwind.layers.WorldMapLayer;
import gov.nasa.worldwind.layers.Earth.BMNGSurfaceLayer;
import gov.nasa.worldwind.layers.Earth.LandsatI3;
import gov.nasa.worldwind.layers.Earth.NASAWFSPlaceNameLayer;
import gov.nasa.worldwind.pick.PickedObjectList;
import gov.nasa.worldwind.render.UserFacingIcon;
import gov.nasa.worldwind.render.WWIcon;
import gov.nasa.worldwind.util.BasicDragger;
import gov.nasa.worldwind.util.StatusBar;
import gov.nasa.worldwind.view.orbit.BasicOrbitView;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.font.TextAttribute;
import java.util.HashMap;

import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.tree.TreePath;

import worldwind.kml.KMLLayer;
import worldwind.kml.KMLParser;
import worldwind.kml.model.KMLFile;
import worldwind.kml.model.KMLPlacemark;
import worldwind.kml.tree.DocListTreeNode;
import worldwind.kml.tree.KMLDocTreeNode;
import worldwind.kml.tree.Sectored;
import worldwind.kml.ui.InfoDialog;


/**
 * @author Tom Gaskins
 * @version $Id: SimpleClient.java 3596 2007-11-20 21:02:34Z tgaskins $
 *
 * Kludged up to show a KMLLayer demo
 */
public class SimpleClient
{
    private static class AWT1UpFrame extends javax.swing.JFrame
    {
        StatusBar statusBar;
        JLabel cursorPositionDisplay;
        WorldWindowGLJPanel wwd;
        DocListTreeNode docList = new DocListTreeNode();
        JTree tree;

        public AWT1UpFrame()
        {
            try
            {
                System.out.println(gov.nasa.worldwind.Version.getVersion());

                wwd = new WorldWindowGLJPanel();
                wwd.addMouseListener(new MouseAdapter() {
                    public void mouseClicked(MouseEvent e) {
                        wwd.grabFocus();
                    }

                    public void mouseEntered(MouseEvent e) {
                        wwd.grabFocus();
                    }
                });

                wwd.setPreferredSize(new java.awt.Dimension(1000, 600));


                //--  Load a couple of example KML files.  Assumes they are in the working directory
                KMLFile file1 = KMLParser.parseFile("app-trail.kml");
                KMLFile file2 = KMLParser.parseFile("KML_Samples.kml");
                KMLFile file3 = KMLParser.parseFile("Vancouver/doc.kml");
                KMLFile file4 = KMLParser.parseFile("tdf2006/doc.kml");
                System.out.println("------------ Track");
                KMLFile file5 = KMLParser.parseFile("Track.kml");
                KMLFile file6 = KMLParser.parseFile("whc-en.kmz");

                //--  Add them to a tree model
                docList.add(new KMLDocTreeNode(file1, "app-trail.kml"));
                docList.add(new KMLDocTreeNode(file2, "KML_Samples.kml"));
                docList.add(new KMLDocTreeNode(file3, "Vancouver.kml"));
                docList.add(new KMLDocTreeNode(file4, "tdf2006.kml"));
                docList.add(new KMLDocTreeNode(file5, "Track.kml"));
                docList.add(new KMLDocTreeNode(file6, "World Heritage"));

                //--  Create a JTree
                tree = new JTree(docList);
                tree.setRootVisible(false);
                tree.setShowsRootHandles(true);

                //--  Double-click on a node in the tree and we'll try to zoom to it.
                //--  This doesn't work too well yet (and doesn't work on folder nodes)
                tree.addMouseListener(new MouseAdapter() {
                    public void mouseClicked(MouseEvent e) {
                        if (e.getClickCount() == 2) {
                            TreePath path = tree.getPathForLocation(e.getX(), e.getY());
                            if (path == null)
                                return;
                            Object obj = path.getLastPathComponent();
                            if (obj instanceof Sectored) {
                                Sector s = ((Sectored)obj).getSector();
                                if (s == null){
                                    System.out.println("Null sector");
                                    return;
                                }

                                View view = wwd.getView();

                                Globe globe = wwd.getModel().getGlobe();
                                if(view instanceof BasicOrbitView) {
                                	BasicOrbitView bov = (BasicOrbitView)view;
                                	
	                                LatLon latLon = new LatLon(Angle.average(s.getMinLatitude(), s.getMaxLatitude()), Angle.average(s.getMinLongitude(), s.getMaxLongitude()));
	
	                                // Stop all animations on the view, and start a 'pan to' animation.
	        						bov.stopAnimations();
	        						bov.addPanToAnimator(new Position(latLon, 0), view.getHeading(), view.getPitch(), 30000);
                                }
                            }
                        }
                    }
                });

                //--  Set up a split view and put the tree on the left
                JSplitPane splitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                        new JScrollPane(tree), wwd);
                splitter.setContinuousLayout(true);
                splitter.setDividerSize(3);
                splitter.setDividerLocation(300);
                //splitter.setEnabled(false);

                this.getContentPane().add(splitter, java.awt.BorderLayout.CENTER);

                this.statusBar = new StatusBar();
                this.getContentPane().add(statusBar, BorderLayout.PAGE_END);

                this.pack();


//                java.awt.Dimension prefSize = this.getPreferredSize();
//                java.awt.Dimension parentSize;
//                java.awt.Point parentLocation = new java.awt.Point(0, 0);
//                parentSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
//                int x = parentLocation.x + (parentSize.width - prefSize.width) / 2;
//                int y = parentLocation.y + (parentSize.height - prefSize.height) / 2;
//                this.setLocation(x, y);
//                this.setResizable(true);
//
//                Model m = (Model) WorldWind.createConfigurationComponent(AVKey.MODEL_CLASS_NAME);
//                LayerList layers = m.getLayers();
//                for (Layer layer : layers)
//                {
//                    if (layer instanceof TiledImageLayer)
//                        ((TiledImageLayer) layer).setShowImageTileOutlines(false);
//                    if (layer instanceof LandsatI3)
//                        ((TiledImageLayer) layer).setDrawBoundingVolumes(false);
//                    if (layer instanceof CompassLayer)
//                        ((CompassLayer) layer).setShowTilt(true);
//                }
//
//                m.getLayers().clear();

                Model m = new BasicModel();
                m.getLayers().clear();
                m.getLayers().add(new BMNGSurfaceLayer());

                LandsatI3 lsi3 = new LandsatI3();
                lsi3.setDrawBoundingVolumes(false);
                lsi3.setOpacity(1);
                m.getLayers().add(lsi3);

                m.getLayers().add(new CompassLayer());
                m.getLayers().add(new NASAWFSPlaceNameLayer());

                //--  Create 3 KML layers and add them on top
                KMLLayer kmlLayer = new KMLLayer(file1);
                m.getLayers().add(kmlLayer);
                kmlLayer = new KMLLayer(file2);
                m.getLayers().add(kmlLayer);
                kmlLayer = new KMLLayer(file3);
                m.getLayers().add(kmlLayer);
                kmlLayer = new KMLLayer(file4);
                m.getLayers().add(kmlLayer);
                kmlLayer = new KMLLayer(file5);
                m.getLayers().add(kmlLayer);
                kmlLayer = new KMLLayer(file6);
                m.getLayers().add(kmlLayer);


//                m.getLayers().add(buildIconLayer());

                m.setShowWireframeExterior(false);
                m.setShowWireframeInterior(false);
                wwd.setModel(m);



                // Forward events to the status bar to provide the cursor position info.
                this.statusBar.setEventSource(wwd);

                this.wwd.addRenderingListener(new RenderingListener()
                {
                    public void stageChanged(RenderingEvent event)
                    {
                        // Do nothing; just showing how to use it.
//                        if (event.getSource() instanceof WorldWindow)
//                        {
//                            Double frameRate = (Double) ((WorldWindow) event.getSource()).getValue(AVKey.FRAME_RATE);
//                            if (frameRate != null)
//                                System.out.println(frameRate);
//                        }
                    }
                });

                this.wwd.addSelectListener(new SelectListener()
                {
                    private WWIcon lastToolTipIcon = null;
                    private BasicDragger dragger = new BasicDragger(wwd);

                    public void selected(SelectEvent event)
                    {
                        if (event.getEventAction().equals(SelectEvent.LEFT_CLICK))
                        {
                            if (event.hasObjects())
                            {

                                System.out.println("Single clicked " + event.getTopObject());

                                //new Exception("Stack Trace").printStackTrace();

                                Object obj = event.getTopObject();
                                if (obj instanceof KMLPlacemark) {
                                    KMLPlacemark pmk = (KMLPlacemark) obj;

                                    if (pmk.getDescription() != null) {
//                                        System.out.println("******\n" + pmk.getDescription());
                                        new InfoDialog(AWT1UpFrame.this, "<html>" + pmk.getDescription() + "</html>");
                                    }
                                }


                                if (event.getTopObject() instanceof WorldMapLayer)
                                {
                                    // Left click on World Map : iterate view to target position
                                    Position targetPos = event.getTopPickedObject().getPosition();
                                    View view = AWT1UpFrame.this.wwd.getView();
                                    if(view instanceof BasicOrbitView) {
                                    	BasicOrbitView bov = (BasicOrbitView)view;
                                    	// Stop all animations on the view, and start a 'pan to' animation.
                						bov.stopAnimations();
                						bov.addPanToAnimator(targetPos, Angle.ZERO, Angle.ZERO, targetPos.getElevation());
                                    }
                                }

                            }
                            else
                                System.out.println("Single clicked " + "no object");
                        }
                        else if (event.getEventAction().equals(SelectEvent.LEFT_DOUBLE_CLICK))
                        {
                            if (event.hasObjects())
                                System.out.println("Double clicked " + event.getTopObject());
                            else
                                System.out.println("Double clicked " + "no object");
                        }
                        else if (event.getEventAction().equals(SelectEvent.RIGHT_CLICK))
                        {
                            if (event.hasObjects())
                                System.out.println("Right clicked " + event.getTopObject());
                            else
                                System.out.println("Right clicked " + "no object");
                        }
                        else if (event.getEventAction().equals(SelectEvent.HOVER))
                        {
                            if (lastToolTipIcon != null)
                            {
                                lastToolTipIcon.setShowToolTip(false);
                                this.lastToolTipIcon = null;
                                AWT1UpFrame.this.wwd.repaint();
                            }

                            if (event.hasObjects() && !this.dragger.isDragging())
                            {
                                if (event.getTopObject() instanceof WWIcon)
                                {
                                    this.lastToolTipIcon = (WWIcon) event.getTopObject();
                                    lastToolTipIcon.setShowToolTip(true);
                                    AWT1UpFrame.this.wwd.repaint();
                                }
                            }
                        }
                        else if (event.getEventAction().equals(SelectEvent.ROLLOVER) && !this.dragger.isDragging())
                        {
                            AWT1UpFrame.this.highlight(event.getTopObject());
                        }
                        else if (event.getEventAction().equals(SelectEvent.DRAG_END)
                            || event.getEventAction().equals(SelectEvent.DRAG))
                        {
                            // Delegate dragging computations to a dragger.
                            this.dragger.selected(event);
                            if (event.getTopObject() instanceof WWIcon)
                            {
                                if (event.getEventAction().equals(SelectEvent.DRAG_END))
                                {
                                    lastPickedIcon.setAlwaysOnTop(false);
                                }
                                else
                                {
                                    lastPickedIcon = (WWIcon) event.getTopObject();
                                    lastPickedIcon.setAlwaysOnTop(true);
                                }
                            }
                            if (event.getEventAction().equals(SelectEvent.DRAG_END))
                            {
                                PickedObjectList pol = wwd.getObjectsAtCurrentPosition();
                                if (pol != null)
                                    AWT1UpFrame.this.highlight(pol.getTopObject());
                            }
                        }
                    }
                });

                this.wwd.addPositionListener(new PositionListener()
                {
                    public void moved(PositionEvent event)
                    {
                        // Do nothing; just show how to add a position listener.
                    }
                });
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }

            wwd.grabFocus();
            
        }

        WWIcon lastPickedIcon;

        private void highlight(Object o)
        {
            if (this.lastPickedIcon == o)
                return; // same thing selected

            if (this.lastPickedIcon != null)
            {
                this.lastPickedIcon.setHighlighted(false);
                this.lastPickedIcon = null;
            }

            if (o != null && o instanceof WWIcon)
            {
                this.lastPickedIcon = (WWIcon) o;
                this.lastPickedIcon.setHighlighted(true);
            }
        }

        private IconLayer buildIconLayer()
        {
            IconLayer layer = new IconLayer();

            for (double lat = 0; lat < 10; lat += 10)
            {
                for (double lon = -180; lon < 180; lon += 10)
                {
                    double alt = 0;
                    if (lon % 90 == 0)
                        alt = 2000000;
                    WWIcon icon = new UserFacingIcon("images/32x32-icon-nasa.png",
                        new Position(Angle.fromDegrees(lat), Angle.fromDegrees(lon), alt));
                    icon.setHighlightScale(1.5);
                    icon.setToolTipFont(this.makeToolTipFont());
                    icon.setToolTipText(icon.getImageSource().toString());
                    icon.setToolTipTextColor(java.awt.Color.YELLOW);
                    layer.addIcon(icon);
                }
            }

            return layer;
        }


        private Font makeToolTipFont()
        {
            HashMap<TextAttribute, Object> fontAttributes = new HashMap<TextAttribute, Object>();

            fontAttributes.put(TextAttribute.BACKGROUND, new java.awt.Color(0.4f, 0.4f, 0.4f, 1f));
            return Font.decode("Arial-BOLD-14").deriveFont(fontAttributes);
        }
    }

    static
    {
        if (gov.nasa.worldwind.Configuration.isMacOS())
        {
            System.setProperty("apple.laf.useScreenMenuBar", "true");
            System.setProperty("com.apple.mrj.application.apple.menu.about.name", "World Wind AWT Canvas App");
            System.setProperty("com.apple.mrj.application.growbox.intrudes", "false");
        }
    }

    public static void main(String[] args)
    {
        System.out.println("Java run-time version: " + System.getProperty("java.version"));

        try
        {
            AWT1UpFrame frame = new AWT1UpFrame();
            frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }


}
